/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package dp1.titandevelop.titano.service;

import dp1.titandevelop.titano.bean.Estado;
import dp1.titandevelop.titano.persistent.Almacen;
import dp1.titandevelop.titano.persistent.AlmacenXProducto;
import dp1.titandevelop.titano.persistent.Empleado;
import dp1.titandevelop.titano.persistent.Kardex;
import dp1.titandevelop.titano.persistent.Lote;
import dp1.titandevelop.titano.persistent.TipoMovimiento;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import org.apache.cayenne.DataObjectUtils;
import org.apache.cayenne.ObjectContext;
import org.apache.cayenne.access.DataContext;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.exp.ExpressionFactory;
import org.apache.cayenne.map.SQLResult;
import org.apache.cayenne.query.EJBQLQuery;
import org.apache.cayenne.query.SQLTemplate;
import org.apache.cayenne.query.SelectQuery;

/**
 *
 * @author Yulian
 */
public class KardexService {

    //Caso en el que no se escribe ningun filtro
    public List<Kardex> buscar(){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        String cadena = "select * from kardex where estado ="+e.getAceptado()+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);         
        List<Kardex> movimientos = context.performQuery(query);
        return movimientos;
    }
    public List<Kardex> buscarPendiente(){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        String cadena = "select * from kardex where estado ="+e.getPendiente()+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);         
        List<Kardex> movimientos = context.performQuery(query);
        return movimientos;
    }
    public boolean aceptoMovimientoProductoDOP(int idDOP,int idProd){
        
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        List<Kardex> movimientos = this.buscarPorDoc(context, idDOP);
        int index=-1;
        
        for(int i=0;i<movimientos.size();i++){
            int idproducto = movimientos.get(i).getToAlmacenXProducto().getToProducto().getIdproducto();
            if(idproducto==idProd){
                index=i;
                break;
            }
        }
        
        if(index>=0){//Producto en el movimiento
            if(movimientos.get(index).getEstado()== e.getAceptado())
                return true;
            else 
                return false;
        }
        else
            return false;
             
    }
    public List<Kardex> buscarPorDoc(int idDoc,int tm){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        String cadena = "select * from kardex where estado = "+e.getPendiente()+"and docAsignado="+idDoc+"and idtipomovimiento="+tm+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);         
        List<Kardex> movimientos = context.performQuery(query);
        return movimientos;
    }
    
    public boolean buscarPorDocAlm(int idDoc,int tm, int alm){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        String cadena = "select * from kardex where idtipomovimiento = "+tm+" and docasignado = "+idDoc+" and estado ="+e.getAceptado()+" and idalmacenxproducto in (select idalmacenxproducto from almacen_x_producto where idalmacen = "+alm+")";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);         
        List<Kardex> movimientos = context.performQuery(query);
        if(movimientos.isEmpty())
            return false;
        else
            return true;
    }
    
    public List<Kardex> buscarPorDoc(ObjectContext c,int idDoc){
        Estado e = new Estado();
        String cadena = "select * from kardex where estado = "+e.getPendiente()+" and docAsignado="+idDoc+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);         
        List<Kardex> movimientos = c.performQuery(query);
        return movimientos;
    }
    public List<Integer> buscarDocsPendientes(){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        SQLTemplate query = new SQLTemplate(Kardex.class,"select docAsignado docs from kardex where estado ="+e.getPendiente()+" group by docAsignado,idtipomovimiento");
        SQLResult resultD = new SQLResult(); 
        resultD.addColumnResult("docs");
        query.setResult(resultD);
        
        List<Integer> docs = context.performQuery(query);
        return docs;
    }
    public List<Integer> buscarTiposMPendientes(){
        Estado e = new Estado();
        ObjectContext context = DataContext.createDataContext();
        SQLTemplate query = new SQLTemplate(Kardex.class,"select idtipomovimiento docs from kardex where estado ="+e.getPendiente()+" group by docAsignado,idtipomovimiento");
        SQLResult resultD = new SQLResult(); 
        resultD.addColumnResult("docs");
        query.setResult(resultD);
        
        List<Integer> docs = context.performQuery(query);
        return docs;
    }
    public Date buscarFechaDoc(int docAsignado){
        ObjectContext c = DataContext.createDataContext();
        String cadena = "select * from kardex where estado = 4 and docasignado="+docAsignado+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);
        List<Kardex> movimientos= c.performQuery(query);
        return movimientos.get(0).getToLote().getFechaingreso();
    }
    public Kardex buscarPorId(ObjectContext c,int idMov){
        Expression q = ExpressionFactory.matchExp(Kardex.IDKARDEX_PK_COLUMN, idMov);
        SelectQuery s = new SelectQuery(Kardex.class, q);
        return (Kardex) DataObjectUtils.objectForQuery(c, s);
    }   
    public List<Kardex> buscarPorIdAXP(ObjectContext c,int idAXP){
      
        String cadena = "select * from kardex where estado = 4 and idalmacenxproducto="+idAXP+"";
        SQLTemplate query = new SQLTemplate(Kardex.class,cadena);
        List<Kardex> movimientos= c.performQuery(query);
        return movimientos;
        
    }    
    public List<AlmacenXProducto> filtraAlmacenProducto(ObjectContext context,int idalm,int idprod){
        AlmacenService servA = new AlmacenService();
        ProductoService servP = new ProductoService();
        
        Expression k0 = ExpressionFactory.greaterExp(AlmacenXProducto.ESTADO_PROPERTY, 0);
        Expression k1; if (idalm!=0) {k1=ExpressionFactory.matchExp(AlmacenXProducto.TO_ALMACEN_PROPERTY,servA.buscarPorId(context, idalm));}else{k1=ExpressionFactory.expTrue();}
        Expression k2; if (idprod!=0) {k2=ExpressionFactory.matchExp(AlmacenXProducto.TO_PRODUCTO_PROPERTY,servP.buscarPorId(context, idprod));}else{k2=ExpressionFactory.expTrue();}      
        Expression k = k0.andExp(k1).andExp(k2);
        
        SelectQuery s = new SelectQuery(AlmacenXProducto.class,k);
        List<AlmacenXProducto> lista = (List<AlmacenXProducto>) context.performQuery(s);
        return lista;
    }
    
    public List<Lote> filtraLote(ObjectContext context,Date in,Date fin,int estado){
        
        SimpleDateFormat formato = new SimpleDateFormat("YYYY/MM/dd");
        
        String cadena1 = "SELECT * FROM lote WHERE ";
        String cadena2; if(in!=null) {cadena2="fechaingreso >= '"+formato.format(in)+"' and ";}else {cadena2="";}
        String cadena3; if(fin!=null) {cadena3="fechaingreso <= '"+formato.format(fin)+"' and ";}else{cadena3="";}
        String cadena4 ="estado ="+estado+""; 
        String cadena0 = cadena1+cadena2+cadena3+cadena4;
        SQLTemplate query = new SQLTemplate(Lote.class,cadena0);
        
        List<Lote> lista = context.performQuery(query);       
        return lista;
    }
    public List<Kardex> filtraKardex(ObjectContext context,String min,String max,int idtmov,int estado){
        TipoMovimientoService servTM = new TipoMovimientoService();
        
        Expression k0 = ExpressionFactory.matchExp(Kardex.ESTADO_PROPERTY, estado);
        Expression k1; if(min!=null){k1=ExpressionFactory.greaterOrEqualExp(Kardex.CANTIDADMOVIMIENTO_PROPERTY,min);}else{k1=ExpressionFactory.expTrue();}
        Expression k2; if(max!=null) {k2=ExpressionFactory.lessOrEqualExp(Kardex.CANTIDADMOVIMIENTO_PROPERTY,max);}else{k2=ExpressionFactory.expTrue();}
        Expression k3; if(idtmov!=0) {k3=ExpressionFactory.matchExp(Kardex.TO_TIPO_MOVIMIENTO_PROPERTY,servTM.buscarPorId(context,idtmov));}else{k3=ExpressionFactory.expTrue();}
        
        Expression k = k0.andExp(k1).andExp(k2).andExp(k3);
        
        SelectQuery s = new SelectQuery(Kardex.class,k);
        //s.addOrdering("idKardex", SortOrder.DESCENDING);
        List<Kardex> lista = (List<Kardex>) context.performQuery(s);
        
       
        return lista;
    }
    public List<Kardex> juntarListas(List<Kardex> listaMov,List<AlmacenXProducto> listaAP,List<Lote> listaLote){
        boolean esta1,esta2;
        if (listaMov != null){
          for(int i=0;i<listaMov.size();i++){
            esta1=false;esta2=false;  
            int idAP = listaMov.get(i).getToAlmacenXProducto().getIdalmacenxproducto();
            int idLote = listaMov.get(i).getToLote().getIdlote();
            if (listaAP != null){
                for(int j=0;j<listaAP.size();j++){
                    if(idAP == listaAP.get(j).getIdalmacenxproducto()){
                        esta1=true;
                        break;
                    }
                }
            }
            if (listaLote != null){
                for(int j=0;j<listaLote.size();j++){
                    if(idLote == listaLote.get(j).getIdlote()){
                        esta2=true;
                        break;
                    }
                }
            }
            if(!(esta1&&esta2)){//Si en alguno no se encuentra se remueve de la lista
                listaMov.remove(i);
                i--;
            }
          }
        }
        return listaMov;
    }
     //Caso en el que se escribe algun filtro
    public List<Kardex> buscarFiltrado(int idalm,int idprod,int idtmov, String min, String max, Date in, Date fin) {
        
        ObjectContext context = DataContext.createDataContext();
        Estado e = new Estado();
        
        List<Kardex> listaMov = this.filtraKardex(context, min, max, idtmov,e.getAceptado());
        List<Lote> listaLote =this.filtraLote(context, in, fin,e.getAceptado());
        List<AlmacenXProducto> listaAP =this.filtraAlmacenProducto(context, idalm, idprod);

        return juntarListas(listaMov,listaAP,listaLote);
    }
    
    public List<Kardex> buscarFiltradoPendiente(int idalm,int idprod,int idtmov, String min, String max, Date in, Date fin) {
        
        ObjectContext context = DataContext.createDataContext();
        Estado e = new Estado();
        
        List<Kardex> listaMov = this.filtraKardex(context, min, max, idtmov,e.getPendiente());
        List<Lote> listaLote =this.filtraLote(context, in, fin,e.getPendiente());
        List<AlmacenXProducto> listaAP =this.filtraAlmacenProducto(context, idalm, idprod);

        return juntarListas(listaMov,listaAP,listaLote);
    }
    

    public void insertar(int idAlm, int idProd, int idTMov, int idEmp, Date in, Date fin,int cantidad) {
                
        ObjectContext context = DataContext.createDataContext();
        Estado estado= new Estado();
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd);       
        
        Expression qualifier = ExpressionFactory.matchExp(Empleado.IDEMPLEADO_PK_COLUMN,idEmp);
        SelectQuery select = new SelectQuery(Empleado.class, qualifier);
        Empleado e = (Empleado) DataObjectUtils.objectForQuery(context, select);
        
        Expression qualifier1 = ExpressionFactory.matchExp(TipoMovimiento.IDTIPOMOVIMIENTO_PK_COLUMN,idTMov);
        SelectQuery select1 = new SelectQuery(TipoMovimiento.class, qualifier1);
        TipoMovimiento tm = (TipoMovimiento) DataObjectUtils.objectForQuery(context, select1);
        
        Lote t = context.newObject(Lote.class);
        t.setFechaingreso(in);
        t.setFechavencimiento(fin);
        t.setEstado(estado.getAceptado());
        
        Kardex k = context.newObject(Kardex.class);   
        k.setCantidadmovimiento(cantidad);
        k.setResponsable(e.getNombres()+" "+e.getApellidop());
        k.setStockanterior(ap.getStock());
        k.setEstado(estado.getAceptado());
        k.setToAlmacenXProducto(ap);
        k.setToLote(t);
        k.setToTipoMovimiento(tm);
        k.setDocasignado(0);
        
        //Actualizamos el almacén
        String cad = tm.getDescripcion();

        actualizaEstadoAlmacen(context,idAlm,idProd,cad,cantidad);
        
        context.commitChanges();
    }
    
       public void insertarConDoc(int idAlm, int idProd, int idTMov, int idEmp, Date in, Date fin,int cantidad, int doc) {
                
        ObjectContext context = DataContext.createDataContext();
        Estado estado= new Estado();
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd);       
        
        Expression qualifier = ExpressionFactory.matchExp(Empleado.IDEMPLEADO_PK_COLUMN,idEmp);
        SelectQuery select = new SelectQuery(Empleado.class, qualifier);
        Empleado e = (Empleado) DataObjectUtils.objectForQuery(context, select);
        
        Expression qualifier1 = ExpressionFactory.matchExp(TipoMovimiento.IDTIPOMOVIMIENTO_PK_COLUMN,idTMov);
        SelectQuery select1 = new SelectQuery(TipoMovimiento.class, qualifier1);
        TipoMovimiento tm = (TipoMovimiento) DataObjectUtils.objectForQuery(context, select1);
        
        Lote t = context.newObject(Lote.class);
        t.setFechaingreso(in);
        t.setFechavencimiento(fin);
        t.setEstado(estado.getAceptado());
        
        Kardex k = context.newObject(Kardex.class);   
        k.setCantidadmovimiento(cantidad);
        k.setResponsable(e.getNombres()+" "+e.getApellidop());
        k.setStockanterior(ap.getStock());
        k.setEstado(estado.getAceptado());
        k.setToAlmacenXProducto(ap);
        k.setToLote(t);
        k.setToTipoMovimiento(tm);
        k.setDocasignado(doc);
        
        //Actualizamos el almacén
        String cad = tm.getDescripcion();

        actualizaEstadoAlmacen(context,idAlm,idProd,cad,cantidad);
        
        context.commitChanges();
    }
public void insertarMovimientoPendiente(int docAsignado,int idAlm, int idProd, int idTMov,int cantidad) {
                
        ObjectContext context = DataContext.createDataContext();
        Estado estado=  new Estado();
        
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd);    
        
        Expression qualifier1 = ExpressionFactory.matchExp(TipoMovimiento.IDTIPOMOVIMIENTO_PK_COLUMN,idTMov);
        SelectQuery select1 = new SelectQuery(TipoMovimiento.class, qualifier1);
        TipoMovimiento tm = (TipoMovimiento) DataObjectUtils.objectForQuery(context, select1);
        
        Calendar cal = Calendar.getInstance();
        Date hoy = new Date();
        cal.add(Calendar.DAY_OF_YEAR, ap.getToProducto().getDiasvencimiento());
        Date  vence = cal.getTime();
        
        Lote t = context.newObject(Lote.class);
        t.setFechaingreso(hoy);
        t.setFechavencimiento(vence);
        t.setEstado(estado.getPendiente());
        
        Kardex k = context.newObject(Kardex.class);   
        
        k.setCantidadmovimiento(cantidad);
        k.setResponsable("");
        k.setStockanterior(ap.getStock());
        k.setEstado(estado.getPendiente());
        k.setToAlmacenXProducto(ap);
        k.setToLote(t);
        k.setToTipoMovimiento(tm);
        k.setDocasignado(docAsignado);
        
        context.commitChanges();
    }

public void insertarMovimientoVenta(int docAsignado,int idAlm, int idProd, int idTMov,int cantidad) {
                
        ObjectContext context = DataContext.createDataContext();
        Estado estado=  new Estado();
        
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd);    
        
        Expression qualifier1 = ExpressionFactory.matchExp(TipoMovimiento.IDTIPOMOVIMIENTO_PK_COLUMN,idTMov);
        SelectQuery select1 = new SelectQuery(TipoMovimiento.class, qualifier1);
        TipoMovimiento tm = (TipoMovimiento) DataObjectUtils.objectForQuery(context, select1);
        
        Calendar cal = Calendar.getInstance();
        Date hoy = new Date();
        cal.add(Calendar.DAY_OF_YEAR, ap.getToProducto().getDiasvencimiento());
        Date  vence = cal.getTime();
        
        Lote t = context.newObject(Lote.class);
        t.setFechaingreso(hoy);
        t.setFechavencimiento(vence);
        t.setEstado(estado.getAceptado());
        
        Kardex k = context.newObject(Kardex.class);   
        
        k.setCantidadmovimiento(cantidad);
        k.setResponsable("");
        k.setStockanterior(ap.getStock());
        k.setEstado(estado.getAceptado());
        k.setToAlmacenXProducto(ap);
        k.setToLote(t);
        k.setToTipoMovimiento(tm);
        k.setDocasignado(docAsignado);
        
        //Actualizamos el almacén
        String cad = tm.getDescripcion();

        actualizaEstadoAlmacen(context,idAlm,idProd,cad,cantidad);
        
        context.commitChanges();
    }

    public void insertar_masivo(int idKardex,int idAlm, int idProd, int idTMov, Date in, Date fin,int cantidad) {
                
        ObjectContext context = DataContext.createDataContext();
        Estado estado= new Estado();
        
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd);
        
        Expression qualifier1 = ExpressionFactory.matchExp(TipoMovimiento.IDTIPOMOVIMIENTO_PK_COLUMN,idTMov);
        SelectQuery select1 = new SelectQuery(TipoMovimiento.class, qualifier1);
        TipoMovimiento tm = (TipoMovimiento) DataObjectUtils.objectForQuery(context, select1);
        
        Lote t = context.newObject(Lote.class);
        t.setFechaingreso(in);
        t.setFechavencimiento(fin);
        t.setEstado(estado.getAceptado());
        
        Kardex k = context.newObject(Kardex.class);  
        k.setIdkardex(idKardex);
        k.setCantidadmovimiento(cantidad);
        k.setResponsable("");
        k.setStockanterior(ap.getStock());
        k.setEstado(estado.getAceptado());
        k.setToAlmacenXProducto(ap);
        k.setToLote(t);
        k.setToTipoMovimiento(tm);
        k.setDocasignado(0);
        
        //Actualizamos el almacén
        String cad = tm.getDescripcion();

        actualizaEstadoAlmacen(context,idAlm,idProd,cad,cantidad);
        
        context.commitChanges();
    }
    public boolean aceptarMovimientoPendiente(int idkardex,int idEmp) {
                
        ObjectContext context = DataContext.createDataContext();
        
        AlmacenXProductoService serv = new AlmacenXProductoService();
        EmpleadoService servEmp = new EmpleadoService();
        Estado estado=  new Estado();      
        Calendar cal = Calendar.getInstance();
        
        //Actualizamos el estado del movimiento, el responsable, el stock previo del almacen
        Kardex k = this.buscarPorId(context, idkardex);        
        Lote t = this.buscarLotePorId(context,k.getToLote().getIdlote());
        
        AlmacenXProducto ap = serv.buscarPorIdAxP(context,k.getToAlmacenXProducto().getIdalmacenxproducto());
        Empleado e = servEmp.buscarPorId(context, idEmp);
        
        Date hoy = new Date();//Día en que se verifica que el movimiento se realizó
        cal.add(Calendar.DAY_OF_YEAR, ap.getToProducto().getDiasvencimiento());
        Date  vence = cal.getTime();//Día que el producto vence apartir de que fue ingresado
        
        //Actualizamos el almacén
        String cad  = k.getToTipoMovimiento().getDescripcion();
        int idAlm   = k.getToAlmacenXProducto().getToAlmacen().getIdalmacen();
        int idProd  = k.getToAlmacenXProducto().getToProducto().getIdproducto();
        int cant    = k.getCantidadmovimiento();
        //Verificamos que haya disponibilidad para entrada o salida
        TipoMovimientoService tm = new TipoMovimientoService();
        List<Integer> disponible = this.disponibilidad(idAlm, idProd);
        
        if((disponible.get(0)>=cant && tm.verificaTipoMov(cad,"Entrada"))||//Caso de entrada de prod a almacen
           (disponible.get(1)>=cant && tm.verificaTipoMov(cad,"Salida"))){ //Caso de salida de un prod de almacen
            
            t.setFechaingreso(hoy);
            t.setFechavencimiento(vence);
            t.setEstado(estado.getAceptado());

            k.setResponsable(e.getNombres()+" "+e.getApellidop());
            k.setStockanterior(ap.getStock());
            k.setEstado(estado.getAceptado());
            
            actualizaEstadoAlmacen(context,idAlm,idProd,cad,cant);//****************************************************
            if(cad.compareTo("Salida Interna")==0){
                AlmacenService servA = new AlmacenService();
                AlmacenXProducto axp = servA.obtenerTemporalPorProd(idProd);
                if(axp!=null)
                   this.insertarMovimientoVenta(k.getDocasignado(),axp.getToAlmacen().getIdalmacen(), idProd, 1, cant);
                    //actualizaEstadoAlmacen(context,axp.getToAlmacen().getIdalmacen(),idProd,"Entrada Interna",cant);
            }
            //**********************************************************************************************************
            context.commitChanges();
            return true;
        }
        else
            return false;
    }
    
    public int eliminar(int idMov) {
        
        ObjectContext context = DataContext.createDataContext();
        
        AlmacenXProductoService serv = new AlmacenXProductoService();        
        Kardex e = this.buscarPorId(context,idMov);        
        AlmacenXProducto ap = serv.buscarPorIdAxP(context,e.getToAlmacenXProducto().getIdalmacenxproducto());
        Lote t = this.buscarLotePorId(context,e.getToLote().getIdlote());
        
        Date hoy = new Date();
        SimpleDateFormat formato = new SimpleDateFormat("YYYY/MM/dd");
//        String cadena = formato.format(hoy);
//        String cadena2 = formato.format(t.getFechaingreso());
        
//        if(cadena2.compareTo(cadena)>=0){
            String cad = e.getToTipoMovimiento().getDescripcion();
            
            if(cad.compareTo("Entrada Interna")==0||cad.compareTo("Entrada Externa")==0||cad.compareTo("Entrada por Devolucion")==0){
                actualizaEstadoAlmacen(context,ap.getToAlmacen().getIdalmacen(),ap.getToProducto().getIdproducto(),"Salida Externa",e.getCantidadmovimiento()); 
            }
            else {
                actualizaEstadoAlmacen(context,ap.getToAlmacen().getIdalmacen(),ap.getToProducto().getIdproducto(),"Entrada Interna",e.getCantidadmovimiento()); 
            }     
            e.setEstado(0);
            t.setEstado(0);
            context.commitChanges();
            return 1;
//        }
//        return 0;

    }

    private Lote buscarLotePorId(ObjectContext c, int idlote) {
        Expression q = ExpressionFactory.matchExp(Lote.IDLOTE_PK_COLUMN, idlote);
        SelectQuery s = new SelectQuery(Lote.class, q);
        return (Lote) DataObjectUtils.objectForQuery(c, s);   
    }    

    public List<Integer> disponibilidad(int idAlm, int idProd) {
        
        ObjectContext context = DataContext.createDataContext();
        List<Integer> datos = new ArrayList<Integer>();
        AlmacenXProductoService serv = new AlmacenXProductoService();
        AlmacenXProducto ap = serv.buscarPorIdAlm_IdProd(context, idAlm, idProd); 
        
        int disponible=ap.getCapacidad()-ap.getStock();
        datos.add(disponible);
        datos.add(ap.getStock());
        return datos;
    }

    public void actualizaEstadoAlmacen(ObjectContext c,int idAlm,int idProd, String cad,int monto) {
        AlmacenService servA = new AlmacenService();
        AlmacenXProductoService servAP = new AlmacenXProductoService();
        Estado e = new Estado();
        
        Almacen alm = servA.buscarPorId(c, idAlm);
        AlmacenXProducto ap = servAP.buscarPorIdAlm_IdProd(c, idAlm, idProd);
        List<AlmacenXProducto> lista = servAP.buscarPorIdAlm(c,idAlm);
        
        int stockFinal=ap.getStock();
        
        if((cad.compareTo("Entrada Interna")==0||cad.compareTo("Entrada Externa")==0)||cad.compareTo("Entrada por Devolucion")==0){
        //Movimiento de entrada y almacen sin usar
            stockFinal+= monto;
            if(alm.getEstado()==e.getSinUsar()){
                alm.setEstado(e.getEnUso());
                ap.setEstado(e.getEnUso());
            }
            else{
                if(ap.getEstado()==e.getSinUsar())
                    ap.setEstado(e.getEnUso());
            } 
        }
        else if((cad.compareTo("Salida Interna")==0||cad.compareTo("Salida Externa")==0)){
            //Si puede salir es debido a que por lo menos un area producto x almacen esta ocupado
            stockFinal-= monto;
            if(stockFinal<=0){//Parte de almacen vaciado  
                stockFinal=0;//Porsiacasoo//******************************************************************************
                ap.setEstado(e.getSinUsar());
            
                boolean flag=false;//Para verificar si existe almenos uno ocupado

                //Se analiza todo el almacen para verificar si estas todas las partes usadas
                for(int i=0;i<lista.size();i++){
                    if(lista.get(i).getIdalmacenxproducto()!= ap.getIdalmacenxproducto()){
                        if(lista.get(i).getEstado()==e.getEnUso()){
                            flag=true;//Existe por lo menos una parte en uso
                            break;
                        }
                    }
                }
                if(!flag) alm.setEstado(e.getSinUsar());
            }            
        }
        ap.setStock(stockFinal);
        c.commitChanges();
    }

    public boolean almUtilizado(ObjectContext c,int idAlm) {
        
        AlmacenXProductoService serv = new AlmacenXProductoService();
        List<AlmacenXProducto> list = serv.buscarPorIdAlm(idAlm);
        
        if(!list.isEmpty()){
            String cad ="("+list.get(0).getIdalmacenxproducto();
            for(int i=1;i<list.size();i++){
                cad+=","+list.get(i).getIdalmacenxproducto();
            }
            cad+=")";
            String cad0 = "select * from kardex where estado >= 1 and idalmacenxproducto in"+cad;
            SQLTemplate query = new SQLTemplate(Kardex.class,cad0);         
            List<Kardex> movimientos = c.performQuery(query);

            if(!movimientos.isEmpty())
                return true;
            else 
                return false;
        }
        else {
            return false;
        }
    }
    
    public boolean tmUtizado(ObjectContext c, int idTm){
        
        String cad = "select * from kardex where estado >= 1 and idTipoMovimiento ="+idTm;
        SQLTemplate query = new SQLTemplate(Kardex.class,cad);         
        List<Kardex> movimientos = c.performQuery(query);
        
        if(!movimientos.isEmpty())
            return true;
        else 
            return false;
    }

    public boolean aceptaSolicitud(int  doc,int tm,int idEmp) {
        DocumentoVentaService servVenta = new DocumentoVentaService();
        OrdenProduccionService servOP = new OrdenProduccionService();
        Estado estado = new Estado();
        
        List<Kardex> movimientos = this.buscarPorDoc(doc,tm);       
        boolean aux = true;
        
        for(int i=0;i<movimientos.size();i++){
            if(!this.aceptarMovimientoPendiente(movimientos.get(i).getIdkardex(),idEmp)){
                aux=false;
            }
            else{//Cambio el estado de un movimiento
                if(reconoceProc(movimientos)==3)//Solo si el mov cambiado es de salida interna indica que la orden de prod esta en proc
                    servOP.cambioEstadoDetalleOP_EnProceso(doc);
            }
        }
        
        if(aux==true){//Se acepta la solicitud si todos los movimientos asignados son aceptadas
           if(reconoceProc(movimientos)==1){
               //Serviciopara actualizar la compra
           }
        }        
        return aux;
    }

    public int reconoceProc(List<Kardex> movimientos) {
        // 1 compra,2 venta, 3 produccion
        if(!movimientos.isEmpty()){
            for(int i=0;i<movimientos.size();i++){
                if(movimientos.get(i).getToTipoMovimiento().getIdtipomovimiento()==2)//Entrada Externa
                    return 1;
                else if(movimientos.get(i).getToTipoMovimiento().getIdtipomovimiento()==4)//Salida Externa
                    return 2;
                else if(movimientos.get(i).getToTipoMovimiento().getIdtipomovimiento()==3)//Salida Interna
                    return 3;
                else if(movimientos.get(i).getToTipoMovimiento().getIdtipomovimiento()==1)//Entrada Interna
                    return 4;
                else 
                    return 2;
            }
        return 4;//Entrada Interna
        }
        else return 0;
    }

    public boolean AlmacenXProductoPendiente(Integer idalmacenxproducto) {
        ObjectContext c = DataContext.createDataContext();
        List<Kardex> list = this.buscarPorIdAXP(c,idalmacenxproducto);
        if (list.isEmpty())
            return false;
        else 
            return true;
    }

    public void inhabilitaMovimientos(ObjectContext c,Integer idordenproduccion) {
        List<Kardex> lista = this.buscarPorDoc(c,idordenproduccion);
        Estado e = new Estado();
        for(int i=0;i<lista.size();i++){
            lista.get(i).setEstado(e.getEliminado());
            c.commitChanges();        
        }
    }
}
